package TestModel;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Random;
import java.util.Set;

import DataModel.CommonLibrary.CGeometricOperations;
import DataModel.CommonLibrary.CommonDefs.Layer;
import DataModel.LayoutManager.CRectangle;
import junit.framework.Assert;
import junit.framework.TestCase;

public class GeometricOperationsTest extends TestCase 
{

	/***************************************************/
	/****** Members ************************************/
	/***************************************************/
	LinkedList<CRectangle> recsList = new LinkedList<CRectangle>();
	CRectangle rec0 = new CRectangle(2,5,4,10,Layer.Metal1,0);
	CRectangle rec1 = new CRectangle(3,6,10,11,Layer.Metal2,1);
	CRectangle rec2 = new CRectangle(8,7,9,8,Layer.Via1_2,2);
	CRectangle rec3 = new CRectangle(7,4,10,12,Layer.Metal1,3);
	CRectangle rec4 = new CRectangle(6,2,11,5,Layer.Metal3,4);
	CRectangle rec5 = new CRectangle(3,1,12,3,Layer.Metal1,5);
	
	
	/***************************************************/
	/****** C'tors *************************************/
	/***************************************************/
	public GeometricOperationsTest()
	{
		recsList.add(rec0);
		recsList.add(rec1);
		recsList.add(rec2);
		recsList.add(rec3);
		recsList.add(rec4);
		recsList.add(rec5);
	}
	
	public void testRecsInHorisontalArea() 
	{
		LinkedList<CRectangle> result = CGeometricOperations.RecsInHorisontalArea(3, 6, recsList);
		
		assertEquals(3, result.size());
		assertEquals(true, result.contains(rec0));
		assertEquals(true, result.contains(rec3));
		assertEquals(true, result.contains(rec4));
	}

	public void testRecsInVerticalArea() {
		LinkedList<CRectangle> result = CGeometricOperations.RecsInVerticalArea(1, 4, recsList);
		
		assertEquals(3, result.size());
		assertEquals(true, result.contains(rec0));
		assertEquals(true, result.contains(rec1));
		assertEquals(true, result.contains(rec5));
	}

	public void testGetBoundingBox() 
	{
		System.out.println("********** Start Get Bounding Box test **********"); 
		
		System.out.println("Leftest edge: " + CGeometricOperations.GetLeftestEdgeRectangle(recsList).getLeftEdge().getStartPoint().x);
		System.out.println("Topest edge: " + CGeometricOperations.GetTopestEdgeRectangle(recsList).getTopEdge().getStartPoint().y);
		System.out.println("Rightest edge: " + CGeometricOperations.GetRightestEdgeRectangle(recsList).getRightEdge().getStartPoint().x);
		System.out.println("Bottomest edge: " + CGeometricOperations.GetBottomestEdgeRectangle(recsList).getBottomEdge().getStartPoint().y);
		System.out.println(CGeometricOperations.GetBoundingBox(recsList).toString());
		
		System.out.println("********** End Get Bounding Box test ********** \n");
	}

	public void testGetRectanglesInArea() 
	{
		LinkedList<CRectangle> result = 
			CGeometricOperations.GetRectanglesInArea(new CRectangle(1,1,4,10,Layer.None,-1), recsList);
		
		assertEquals(3, result.size());
		assertEquals(true, result.contains(rec0));
		assertEquals(true, result.contains(rec1));
		assertEquals(true, result.contains(rec5));
	}

	public void testGetLeftestEdgeRectangle() 
	{
		CRectangle result = 
			CGeometricOperations.GetLeftestEdgeRectangle(recsList);
		
		assertEquals(true, result.equals(rec0));
	}

	public void testGetRightestEdgeRectangle() 
	{
		CRectangle result = 
			CGeometricOperations.GetRightestEdgeRectangle(recsList);
		
		assertEquals(true, result.equals(rec5));
	}

	public void testGetTopestEdgeRectangle() 
	{
		CRectangle result = 
			CGeometricOperations.GetTopestEdgeRectangle(recsList);
		
		assertEquals(true, result.equals(rec3));
	}

	public void testGetBottomestEdgeRectangle() 
	{
		CRectangle result = 
			CGeometricOperations.GetBottomestEdgeRectangle(recsList);
		
		assertEquals(true, result.equals(rec5));
	}

	public void testRectanglesIntersection() 
	{
		Hashtable<Long, LinkedList<CRectangle>> recsConnected = new Hashtable<Long, LinkedList<CRectangle>>();
		CGeometricOperations.rectanglesIntersection(recsList, recsConnected);

		for (Iterator iterator = recsConnected.keySet().iterator(); iterator.hasNext();) 
		{
			Long key = (Long) iterator.next();
			
			if(key == 5){
				assertEquals(true, recsConnected.get(key).contains(rec4));
			}
			else if(key == 4){
				assertEquals(true, recsConnected.get(key).contains(rec3));
				assertEquals(true, recsConnected.get(key).contains(rec5));				
			}
			else if(key == 3){
				assertEquals(true, recsConnected.get(key).contains(rec1));
				assertEquals(true, recsConnected.get(key).contains(rec2));
				assertEquals(true, recsConnected.get(key).contains(rec4));	
			}
			else if(key == 2){
				assertEquals(true, recsConnected.get(key).contains(rec1));
				assertEquals(true, recsConnected.get(key).contains(rec3));
			}
			else if(key == 1){
				assertEquals(true, recsConnected.get(key).contains(rec0));
				assertEquals(true, recsConnected.get(key).contains(rec2));
				assertEquals(true, recsConnected.get(key).contains(rec3));
			}
			else if(key == 0){
				assertEquals(true, recsConnected.get(key).contains(rec1));
			}
		}
	}
}
